From 3ec6777498773932c6383c2bfc7b05523f6ca45f Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 1 Oct 2009 12:29:33 +0100 Subject: [PATCH] Fix recursive lock p2m lock acquisition in POD code The POD code can take the p2m lock from inside a lookup. This causes a crash if anyone calls gfn_to_mfn* with the p2m lock held, which is quite a few places. Make the POD code understand that it may be called with the lock held, and DTRT about talking or releasing it. Signed-off-by: Tim Deegan --- xen/arch/x86/mm/p2m.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 10021b7102..77ed7f2ca5 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1067,21 +1067,29 @@ static int p2m_pod_check_and_populate(struct domain *d, unsigned long gfn, l1_pgentry_t *p2m_entry, int order, p2m_query_t q) { + /* Only take the lock if we don't already have it. Otherwise it + * wouldn't be safe to do p2m lookups with the p2m lock held */ + int do_locking = !p2m_locked_by_me(d->arch.p2m); int r; - p2m_lock(d->arch.p2m); + + if ( do_locking ) + p2m_lock(d->arch.p2m); + audit_p2m(d); /* Check to make sure this is still PoD */ if ( p2m_flags_to_type(l1e_get_flags(*p2m_entry)) != p2m_populate_on_demand ) { - p2m_unlock(d->arch.p2m); + if ( do_locking ) + p2m_unlock(d->arch.p2m); return 0; } r = p2m_pod_demand_populate(d, gfn, order, q); audit_p2m(d); - p2m_unlock(d->arch.p2m); + if ( do_locking ) + p2m_unlock(d->arch.p2m); return r; } -- 2.30.2